﻿using Furion;
using System;

namespace Microsoft.Extensions.Caching.Distributed
{
    public static class DistributedCacheEntryOptionsExtensions
    {
        /// <summary>
        /// 获取长分布式缓存选项
        /// </summary>
        /// <param name="distributedCache"></param>
        /// <returns></returns>
        public static DistributedCacheEntryOptions GetLongDistributedCacheEntryOptions(this IDistributedCache distributedCache)
        {
            TimeSpan slidingExpiration = distributedCache.GetDistributedCacheSlidingExpiration("DistributedCache:LongSlidingExpiration", "DistributedCache:LongFloatingAbsolute");
            DistributedCacheEntryOptions distributedCacheEntryOptions = new DistributedCacheEntryOptions
            {
                SlidingExpiration = slidingExpiration
            };
            return distributedCacheEntryOptions;
        }

        /// <summary>
        /// 获取默认分布式缓存选项
        /// </summary>
        /// <param name="distributedCache"></param>
        /// <returns></returns>
        public static DistributedCacheEntryOptions GetDefaultDistributedCacheEntryOptions(this IDistributedCache distributedCache)
        {
            TimeSpan slidingExpiration = distributedCache.GetDistributedCacheSlidingExpiration("DistributedCache:SlidingExpiration", "DistributedCache:FloatingAbsolute");
            DistributedCacheEntryOptions distributedCacheEntryOptions = new DistributedCacheEntryOptions
            {
                SlidingExpiration = slidingExpiration
            };
            return distributedCacheEntryOptions;
        }

        /// <summary>
        /// 获取分布式缓存滑动截止时间
        /// </summary>
        /// <param name="distributedCache"></param>
        /// <param name="slidingExpirationKey"></param>
        /// <param name="floatingAbsoluteKey"></param>
        /// <returns></returns>
        public static TimeSpan GetDistributedCacheSlidingExpiration(this IDistributedCache distributedCache, string slidingExpirationKey, string floatingAbsoluteKey, bool isDefault = true)
        {
            double slidingExpiration;
            int floatingAbsolute;
            try
            {
                slidingExpiration = double.Parse(App.Configuration[slidingExpirationKey]);
                floatingAbsolute = Math.Abs(int.Parse(App.Configuration[floatingAbsoluteKey]));
            }
            catch
            {
                slidingExpiration = isDefault ? 30 : 60;
                floatingAbsolute = isDefault ? 1 : 2;
            }

            Random random = new Random();
            double nextDouble = random.NextDouble();
            int randomNo = random.Next(-floatingAbsolute, floatingAbsolute);
            return TimeSpan.FromMinutes(slidingExpiration + nextDouble * randomNo + randomNo < 0 ? -nextDouble : nextDouble);
        }
    }
}
